package org.high5.paintmyworld;

import java.util.Random;

import org.high5.model.CanvasCoordinates;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.widget.ImageView;

public class PrettyLine extends Canvas {
	
	public static final int COLOR_MAX = 255;
	public static final int PAINT_ALPHA = 50;
	
	private int mHeight, mWidth;
	private ImageView mImageView;
	private CanvasCoordinatesExtended[] mCanvasCoordinates;
	private Paint mPaint = new Paint();
    private Random mRandom = new Random();
    private Bitmap[] mBitmap;
    private int mMasterScale, mFrameNo;
    private boolean mFramesFilled;
	
	public PrettyLine (int width, int height, ImageView imageView){
		
		super();
		resize(width, height);
		
		mImageView = imageView;
        
        mMasterScale = 1;
        
	}
	
	public void redraw(CanvasCoordinates[] cc) throws Exception{
		mFramesFilled = false;
		mBitmap = new Bitmap[5];
		int arraySize = cc.length;
		mCanvasCoordinates = new CanvasCoordinatesExtended[arraySize];
		if(arraySize>1){
			mCanvasCoordinates[0] = new CanvasCoordinatesExtended(cc[0],null,cc[1]);
			for(int i=1; i<arraySize-1;i++){
				mCanvasCoordinates[i] = new CanvasCoordinatesExtended(cc[i],cc[i-1],cc[i+1]);
			}
			mCanvasCoordinates[arraySize-1] = new CanvasCoordinatesExtended(cc[arraySize-1],cc[arraySize-2],null);
		}else{
			throw new Exception("Coordinate array must be of at least size two.");
		}
	}
	
	public void resize(int width, int height){
		mWidth = width;
		mHeight = height;
	}
	
	public void draw(){
		
		// TODO Save the Bitmaps to an array list for increased frame rate.
		
		
        
		if(mCanvasCoordinates!=null&&!mFramesFilled){
			
			mBitmap[mFrameNo] = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
	        setBitmap(mBitmap[mFrameNo]);
	        
			for(int i = 0; i<mCanvasCoordinates.length-1; i++){
				double altitude = mCanvasCoordinates[i].getAltitude();
				double speed = mCanvasCoordinates[i].getSpeed();
				
	        	
	        	for(double j = 0; j < speed; j+=10.0){
	        		
	        		double deltaAlt = mCanvasCoordinates[i].getDeltaAlt();
	        		int blue = (int)(altitude+deltaAlt*j/2);
	        		int red = COLOR_MAX-blue;
	        		mPaint.setARGB(PAINT_ALPHA*3, red, 0, blue);
	        		
	        		double x = mRandom.nextInt(mWidth /40)+mCanvasCoordinates[i].getX()+mCanvasCoordinates[i].getDeltaX()*j-10;
	        		double y = mRandom.nextInt(mHeight/40)+mCanvasCoordinates[i].getY()+mCanvasCoordinates[i].getDeltaY()*j-10;
	        		
	        		double distanceFromLast = distanceOfTwoCoordinates(x,y,mCanvasCoordinates[i].getX(),mCanvasCoordinates[i].getY());
	        		double distanceToNext = distanceOfTwoCoordinates(x,y,mCanvasCoordinates[i+1].getX(),mCanvasCoordinates[i+1].getY());
	        		double closest;
	        		if(distanceFromLast>distanceToNext)
	        			closest = distanceToNext;
	        		else
	        			closest = distanceFromLast;
	        		
	        		int smallestDimension;
	        		
	        		if(mWidth>mHeight)
	        			smallestDimension = mHeight;
	        		else
	        			smallestDimension = mWidth;
	        		
	        		double size = (smallestDimension-closest)/12-40;
	        		if(size<5)
	        			size = 5.0;
	        		drawCircle((float)x, (float)y, (int)(size+mRandom.nextInt(20)/(10.0/mMasterScale)), mPaint);
	        		mPaint.setARGB(PAINT_ALPHA, Math.abs(red-100), 0, Math.abs(blue-100));
	        		drawCircle((float)x+5, (float)y+5, (int)(size+mRandom.nextInt(20)/(10.0/mMasterScale)), mPaint);
	        	}
	        	
	        	int blue = (int)(altitude);
        		int red = COLOR_MAX-blue;
        		mPaint.setARGB(PAINT_ALPHA*3, 0, 0, 0);
	        	drawCircle((float)mCanvasCoordinates[i].getX()+4, (float)mCanvasCoordinates[i].getY()+4, (int)((mMasterScale+20)*2), mPaint);
        		mPaint.setARGB(PAINT_ALPHA*3, red, 0, blue);
	        	drawCircle((float)mCanvasCoordinates[i].getX(), (float)mCanvasCoordinates[i].getY(), (int)((mMasterScale+20)*2), mPaint);
	        	
	        	
	        	
	        	
	        	if(mFrameNo==2)
		       		mFramesFilled=true;
			
			}
		}else if(mCanvasCoordinates!=null){
			setBitmap(mBitmap[mFrameNo]);
		}
	    mImageView.setImageBitmap(mBitmap[mFrameNo++]);
	       	
	    mFrameNo%=3;	
	}
	
	
	private static double distanceOfTwoCoordinates(double x1, double y1, double x2, double y2){
		return Math.sqrt(Math.abs(Math.pow((x2-x1),2.0)+Math.pow((y2-y1),2.0)));
	}
}


